package com.xbongbong.saas.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.distributor.dto.DistributorContactDeleteBatchDTO;
import com.xbongbong.distributor.dto.DistributorDeleteBatchDTO;
import com.xbongbong.distributor.dto.DistributorEditAttrUpdateDTO;
import com.xbongbong.distributor.dto.DistributorUpdateBatchDTO;
import com.xbongbong.distributor.dto.DistributorUpdateDTO;
import com.xbongbong.distributor.vo.DistributorDeleteBatchVO;
import com.xbongbong.distributor.vo.DistributorEditAttrUpdateVO;
import com.xbongbong.distributor.vo.DistributorUpdateBatchVO;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.AttrValuePojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.FormDataThoroughDeleteDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.DepartmentService;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.contactuser.pojo.dto.ContactUserDeleteBatchDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerCommunicateDeleteBatchDTO;
import com.xbongbong.pro.customeruser.pojo.dto.CustomerUserDeleteBatchDTO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ContactErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.DistributorErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceDeleteBatchDTO;
import com.xbongbong.pro.message.constant.DistributorPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.pushnotify.dto.PushNotifyDeleteDTO;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.service.toolbox.elasticsearch.help.ProEsHelper;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.DistributorAccountEntity;
import com.xbongbong.saas.domain.entity.PaymentBalanceEntity;
import com.xbongbong.saas.domain.entity.ext.CreditLimitEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.DistributorAddressEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.LinkAddOperationFlagEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CreditLimitEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.DistributorAccountEnum;
import com.xbongbong.saas.enums.business.DistributorContactEnum;
import com.xbongbong.saas.enums.business.DistributorEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.OrderEnum;
import com.xbongbong.saas.enums.business.PaymentBalanceEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.LogHandleHelp;
import com.xbongbong.saas.help.SaasCreditHelper;
import com.xbongbong.saas.help.SaasDeleteHelp;
import com.xbongbong.saas.help.SaasDetailPermissionHelp;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.DistributorAccountModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.service.ContactUserService;
import com.xbongbong.saas.service.CustomerUserService;
import com.xbongbong.saas.service.DistributorCommunicateService;
import com.xbongbong.saas.service.DistributorContactService;
import com.xbongbong.saas.service.DistributorManageService;
import com.xbongbong.saas.service.InvoiceService;
import com.xbongbong.saas.service.PaymentBalanceService;
import com.xbongbong.saas.service.PaymentSheetService;
import com.xbongbong.saas.service.PushNotifyService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author xinpeng.jiang
 * @version 1.0
 * @date 2020/12/22 15:59
 * @since V1.0
 */
@Service("distributorManageService")
public class DistributorManageServiceImpl implements DistributorManageService {

    private static final Logger LOG = LoggerFactory.getLogger(DistributorManageServiceImpl.class);

    @Resource
    private UserTeamService userTeamService;
    @Resource
    private UserModel userModel;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    @Lazy
    private CustomerCommunicateServiceImpl customerCommunicateService;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private DistributorContactService distributorContactService;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private SaasDetailPermissionHelp saasDetailPermissionHelp;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private CustomerUserService customerUserService;
    @Resource
    private PushNotifyService pushNotifyService;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private ContactUserService contactUserService;
    @Resource
    private DistributorCommunicateService distributorCommunicateService;
    @Resource
    private ProEsHelper proEsHelper;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private InvoiceService invoiceService;
    @Resource
    private PaymentSheetService paymentSheetService;
    @Resource
    private PaymentBalanceService paymentBalanceService;
    @Resource
    private DistributorAccountModel distributorAccountModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private SaasCreditHelper saasCreditHelper;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private LogHandleHelp logHandleHelp;

    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
    }

    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        JSONObject data = validateDataDTO.getData();
        String corpid = validateDataDTO.getCorpid();
        Long dataId = validateDataDTO.getDataId();
        String name = FastJsonHelper.getStringFromFormData(data, DistributorEnum.NAME.getAttr());
        Long formId = validateDataDTO.getFormId();
        String creatorId = FastJsonHelper.getStringFromFormData(data, DistributorEnum.CREATOR_ID.getAttr());
        // if (StringUtil.isEmpty(creatorId)) {
        //     data.put(DistributorEnum.CREATOR_ID.getAttr(), validateDataDTO.getUserId());
        // }
        // if (Objects.nonNull(validateDataDTO.getOwnerIds()) && !validateDataDTO.getOwnerIds().isEmpty()) {
        //     // 新建有负责人设置其分配时间
        //     if (dataId == null) {
        //         data.put(DistributorEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
        //     }
        // }
        // 关联新建
        JSONArray contactArray = FastJsonHelper.getJsonArrFromFormData(data, DistributorEnum.ADD_CONTACT.getAttr());
        if (contactArray != null) {
            // 校验联系人
            verifyContact(corpid, contactArray, dataId, name, validateDataDTO);
        }
        data.put(DistributorEnum.ADD_CONTACT.getAttr(), contactArray);
        // 公海池逻辑先保留
        data.put(DistributorEnum.IS_PUBLIC.getAttr(), Constant.ZERO);
        // 校验收货地址默认校验
        JSONArray shippingAddressArr = data.getJSONArray(DistributorEnum.SHIPPING_ADDRESS.getAttr());
        if (CollectionsUtil.isNotEmpty(shippingAddressArr)) {
            boolean defaultTrue = false;
            for (Object item : shippingAddressArr) {
                Integer addressDefault = ((JSONObject) item).getInteger(DistributorAddressEnum.SET_DEFAULT.getAttr());
                if (defaultTrue && Objects.equals(addressDefault, BasicConstant.ONE)) {
                    throw new XbbException(DistributorErrorCodeEnum.API_ERROR_251007.getCode(), DistributorErrorCodeEnum.API_ERROR_251007.getMsg());
                } else if (Objects.equals(addressDefault, BasicConstant.ONE)) {
                    defaultTrue = true;
                }
            }
        }

        // for (Map.Entry<String,Object> entry : SaasDataInitHelp.initCustomer().entrySet()){
        //     SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
        // }
    }

    @Override
    public void afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String corpid = saasFormSaveDTO.getCorpid();
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONObject oldData = saasFormSaveDTO.getOldData();
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long dataId = newPaasFormDataEntity.getId();
        Boolean isNew = saasFormSaveDTO.getIsNew();
        Long formId = newPaasFormDataEntity.getFormId();
        String distributorName = FastJsonHelper.getStringOrDefaultFromFormData(newData, DistributorEnum.NAME.getAttr(), "");
        SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo();
        if (Objects.nonNull(saasNeedRedundantAttrPoJo)) {
//            BeforeSaveMyTeamDTO beforeSaveMyTeamDTO = saasNeedRedundantAttrPoJo.getBeforeSaveMyTeamDTO();
//            if (beforeSaveMyTeamDTO != null) {
//                beforeSaveMyTeamDTO.setDataId(dataId);
//                UserTeamBatchSaveDTO userTeamBatchSaveDTO = userTeamService.beforeSaveMyTeam(beforeSaveMyTeamDTO);
//                userTeamBatchSaveDTO.setIsCustomerNew(isNew);
//                userTeamBatchSaveDTO.setLoginUser(saasFormSaveDTO.getLoginUser());
//                userTeamService.saveMyTeam(userTeamBatchSaveDTO);
//            }
            teamDataHelp.saveUserTeam(saasNeedRedundantAttrPoJo, dataId, newPaasFormDataEntity, saasFormSaveDTO.getIsImport(), false);

        }
        Runnable runnable = () -> {
            if (isNew) {
                String creatorId = newPaasFormDataEntity.getCreatorId();
                UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                try {
                    // 经销商创建项目日志(经销商动态)
                    String typeName = XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getName();
                    String operate = Objects.equals(saasFormSaveDTO.getIsImport(), 1) ? I18nMessageUtil.getMessage(I18nStringConstant.IMPORTED) : I18nMessageUtil.getMessage(I18nStringConstant.ADD);
                    String creatorUserName = Objects.isNull(creatorUser) ? "" : creatorUser.getName();
                    String communicateMemo = creatorUserName + operate + typeName + ":" + distributorName;
                    customerCommunicateService.addCustomerDynamic(saasFormSaveDTO.getCorpid(), creatorId, communicateMemo, dataId, distributorName, ProjectLogEnum.DISTRIBUTOR_CREATE.getSubType());
                } catch (Exception e) {
                    LOG.error("经销商创建项目日志", e);
                }

                try {
                    if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                        // 经销商创建消息推送
                        CustomerEntityExt customerEntityExt = new CustomerEntityExt();
                        BeanUtil.copyProperties(newPaasFormDataEntity, customerEntityExt);
                        List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(saasFormSaveDTO.getCorpid(), PushTypeEnum.DISTRIBUTOR_ADD_PUSH.getCode(), PushTypeEnum.DISTRIBUTOR_ADD_PUSH.getSubCode(), creatorUser, customerEntityExt);
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(newPaasFormDataEntity.getAppId(), newPaasFormDataEntity.getMenuId(), newPaasFormDataEntity.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getSubBusinessType());
                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(saasFormSaveDTO.getCorpid(), pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_ADD_TITLE), String.format(I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_ADD_CONTENT), creatorUser.getName(), distributorName), null, options);
                        baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_ADD_PUSH, messageRabbitMqDTO);
                    }
                } catch (Exception e) {
                    LOG.error("经销商创建消息推送", e);
                }
            } else {
                paasRedisHelper.removeHashValue(RedisPrefixConstant.DISTRIBUTOR_CATEGORY_INFO, corpid, dataId.toString());
            }
        };
        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
    }

    @Override
    public void verifyContact(String corpid, JSONArray contactArray, Long dataId, String name, ValidateDataDTO validateDataDTO) throws XbbException {
        JSONArray linkCustomerArray = new JSONArray();
        JSONObject linkCustomerObj = new JSONObject();
        Integer distributorMark = DistributorMarkEnum.DISTRIBUTOR.getCode();
        linkCustomerObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, dataId);
        linkCustomerObj.put(StringConstant.SAAS_LINK_BUSINESS_NAME, name);
        linkCustomerArray.add(linkCustomerObj);
        // 获取联系人的解释和必要信息
        PaasFormExplainEntity contactFormExplainEntity = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.CONTACT.getCode(), corpid, distributorMark);
        Map<String, FieldAttrEntity> contactExplainMap = ExplainUtil.getExplainMap(contactFormExplainEntity.getExplains(), "");

        // fix: 19222 【客户管理】关联新建联系人，设置联系人名称不允许有重复值，但是新增的时候仍然能保存成功。
        // 不允许姓名重复时才做处理
        Integer noRepeat = contactExplainMap.get(DistributorContactEnum.NAME.getAttr()).getNoRepeat();
        if (Objects.nonNull(noRepeat) && Objects.equals(1, noRepeat)) {
            Set<String> contactNameSet = new HashSet<>();
            JSONArray contactAddArray = new JSONArray();
            contactArray.forEach(obj -> {
                JSONObject contactObj = (JSONObject) obj;
                // 排除删除联系人的情况，只做新增联系人时排重
                Integer operationFlag = contactObj.getInteger(StringConstant.OPERATION_FLAG);
                if (!Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode())) {
                    JSONObject contactData = contactObj.getJSONObject(StringConstant.JSON_DATA);
                    contactNameSet.add(contactData.getString(DistributorContactEnum.NAME.getAttr()));
                    contactAddArray.add(contactObj);
                }
            });
            if (contactNameSet.size() < contactAddArray.size()) {
                throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201033);
            }
        }
        // 联系人公共部分属性
        ValidateDataDTO contactValidateDataDTO = new ValidateDataDTO();
        SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
        saasNeedRedundantAttrPojo.setIsRelationItem(1);
        BeanUtil.copyProperties(validateDataDTO, contactValidateDataDTO);
        BeanUtil.copyProperties(contactFormExplainEntity, contactValidateDataDTO);
        contactValidateDataDTO.setExplainMap(contactExplainMap);
        // 每个联系人的data和dataId赋值
        List<ValidateDataDTO> needAddValidateDataDTO = new ArrayList<>();
        List<ValidateDataDTO> needDelValidateDataDTO = new ArrayList<>();
        List<ValidateDataDTO> needUpdateValidateDataDTO = new ArrayList<>();
        List<String> contactPhoneList = new ArrayList<>();
        JSONArray newContactArr = new JSONArray();
        List<String> noRepeatAttr = new ArrayList<>();
        contactExplainMap.entrySet().forEach(entry -> {
            if (Objects.equals(entry.getValue().getNoRepeat(), 1)) {
                noRepeatAttr.add(entry.getKey());
            }
        });
        Map<String, Long> delPhoneMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Map<String, Long>> noRepeatMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        int contactNum = contactArray.size();
        for (Object obj : contactArray) {
            // 单个联系人数据
            JSONObject contactObj = (JSONObject) obj;
            // 表示编辑时数据是否被更改，被更改operationFlag为1,被删除operationFlag为2
            Integer operationFlag = contactObj.getInteger(StringConstant.OPERATION_FLAG);
            // 联系人的data数据
            JSONObject contactData = contactObj.getJSONObject(StringConstant.JSON_DATA);
            Long contactDataId = contactObj.getLong(StringConstant.DATA_ID);
            if (Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode()) && Objects.nonNull(contactDataId)) {
                contactNum--;
                List<String> phoneListFromFormData = FastJsonHelper.getPhoneListFromFormData(contactData, DistributorContactEnum.PHONE.getAttr());
                for (String phone : phoneListFromFormData) {
                    delPhoneMap.put(phone, contactDataId);
                }
                for (String attr : noRepeatAttr) {
                    Map<String, Long> noRepeatDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    if (noRepeatMap.containsKey(attr)) {
                        noRepeatDataMap = noRepeatMap.get(attr);
                    }
                    noRepeatDataMap.put(contactData.getString(attr), contactDataId);
                    noRepeatMap.put(attr, noRepeatDataMap);
                }
            }
        }
        // 只有一个联系人时，设置该联系人为主联系人
        if (1 == contactNum) {
            JSONObject contactObj = (JSONObject) contactArray.get(0);
            JSONObject data = contactObj.getJSONObject(StringConstant.JSON_DATA);
            data.put(DistributorContactEnum.IS_MAIN.getAttr(), BasicConstant.ONE);
        }
        for (Object obj : contactArray) {
            // 单个联系人数据
            JSONObject contactObj = (JSONObject) obj;
            // 表示编辑时数据是否被更改，被更改operationFlag为1,被删除operationFlag为2
            Integer operationFlag = contactObj.getInteger(StringConstant.OPERATION_FLAG);
            // 联系人的data数据
            JSONObject contactData = contactObj.getJSONObject(StringConstant.JSON_DATA);
            Long contactDataId = contactObj.getLong(StringConstant.DATA_ID);
            contactValidateDataDTO.setDataId(contactDataId);
            contactValidateDataDTO.setSerialNo(contactObj.getString(FieldTypeEnum.SERIALNO.getAlias()));
            contactValidateDataDTO.setImportDelContact(null);

            // 去掉传来的关联客户属性来兼容新建 提前为了让审批数据格式一致
            contactData.remove(DistributorContactEnum.DISTRIBUTOR_NAME.getAttr());
            contactData.remove(DistributorContactEnum.DISTRIBUTOR_NAME_LINK_TEXT.getAttr());
            contactData.put(DistributorContactEnum.DISTRIBUTOR_NAME.getAttr(), linkCustomerArray);
            contactValidateDataDTO.setData(contactData);
            saasNeedRedundantAttrPojo.setContactPhoneList(contactPhoneList);
            contactValidateDataDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
            ProSaveHelp.analyticalData(contactValidateDataDTO);
            List<String> phoneListFromFormData = FastJsonHelper.getPhoneListFromFormData(contactData, DistributorContactEnum.PHONE.getAttr());
            if (Objects.isNull(contactDataId)) {
                for (String phone : phoneListFromFormData) {
                    if (delPhoneMap.containsKey(phone)) {
                        contactValidateDataDTO.setDataId(delPhoneMap.get(phone));
                        contactValidateDataDTO.setImportDelContact(1);
                    }
                }
                for (String attr : noRepeatAttr) {
                    if (MapUtils.isNotEmpty(noRepeatMap) && noRepeatMap.containsKey(attr)
                            && noRepeatMap.get(attr).containsKey(contactData.getString(attr))) {
                        contactValidateDataDTO.setDataId(noRepeatMap.get(attr).get(contactData.getString(attr)));
                        contactValidateDataDTO.setImportDelContact(1);
                    }
                }
            }
            try {
                // fix: 26324 【成功部】字段填写完整报错报错提示“联系人类型没有填写”
                //  如果联系人已经删除 就跳过此校验
                if (!Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode())) {
                    formDataValidateDataHelp.validateData(contactValidateDataDTO);
                }
            } catch (XbbException e) {
                if (Objects.equals(e.getCode(), SystemErrorCodeEnum.API_ERROR_100034.getCode())) {
                    throw new XbbException(ContactErrorCodeEnum.API_ERROR_204008);
                } else {
                    throw e;
                }
            }
            distributorContactService.beforeSave(contactValidateDataDTO);
            if (Objects.equals(contactValidateDataDTO.getImportDelContact(), 1)) {
                contactValidateDataDTO.setDataId(null);
            }
            contactPhoneList.addAll(phoneListFromFormData);

            if (contactDataId != null) {
                if (Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode())) {
                    ValidateDataDTO newDelContactDTO = new ValidateDataDTO();
                    BeanUtil.copyProperties(contactValidateDataDTO, newDelContactDTO);
                    needDelValidateDataDTO.add(newDelContactDTO);
                    continue;
                }
                // 没有更改的的联系人
                if (!Objects.equals(operationFlag, LinkAddOperationFlagEnum.EDIT.getCode())) {
                    continue;
                }
            }

            if (contactDataId != null) {
                ValidateDataDTO newUpdateContactDTO = new ValidateDataDTO();
                BeanUtil.copyProperties(contactValidateDataDTO, newUpdateContactDTO);
                needUpdateValidateDataDTO.add(newUpdateContactDTO);
            } else {
                ValidateDataDTO newAddContactDTO = new ValidateDataDTO();
                BeanUtil.copyProperties(contactValidateDataDTO, newAddContactDTO);
                needAddValidateDataDTO.add(newAddContactDTO);
            }
            newContactArr.add(contactData);
        }
        contactArray = newContactArr;
        SaasNeedRedundantAttrPojo customerPojo = new SaasNeedRedundantAttrPojo();
        customerPojo.setNeedAddValidateDataDTO(needAddValidateDataDTO);
        customerPojo.setNeedDelValidateDataDTO(needDelValidateDataDTO);
        customerPojo.setNeedUpdateValidateDataDTO(needUpdateValidateDataDTO);
        validateDataDTO.setSaasNeedRedundantAttrPoJo(customerPojo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DistributorDeleteBatchVO deleteBatch(DistributorDeleteBatchDTO distributorDeleteBatchDTO) throws XbbException {
        DistributorDeleteBatchVO distributorDeleteBatchVO = new DistributorDeleteBatchVO();
        String corpid = distributorDeleteBatchDTO.getCorpid();
        List<Long> distributorCommunicateIdIn = new ArrayList<>();
        List<Long> invoiceIdIn = new ArrayList<>();
        // List<Long> opportunityIdIn = new ArrayList<>();
        List<Long> contactIdIn = new ArrayList<>();
        // List<Long> quotationIdIn = new ArrayList<>();
        Set<Long> deletePayMentBalanceId = new HashSet<>();
        List<Long> distributorIdIn = distributorDeleteBatchDTO.getDataIdList();
        Set<String> errorTypeSet = new HashSet<>();
        List<Long> allowDeleteDistributorId = new ArrayList<>();
        List<String> errorDataList = new ArrayList<>();
        try {
            // 过滤不允许删除的经销商
            List<String> name = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String, Object> param = BeanUtil.convertBean2Map(distributorDeleteBatchDTO, true);
            param.put("ids", distributorIdIn);
            param.put("del", DelEnum.NORMAL.getDel());
            List<CustomerEntityExt> distributorList = customerModel.findEntitys(param);
            if (Objects.isNull(distributorList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 获取有订货单的经销商
            BoolQueryBuilder booleanQuery = boolQuery();
            String linkDistributorAttr = OrderEnum.LINK_DISTRIBUTOR.getAttr();
            String linkDistributor = StringConstant.JSON_DATA +StringConstant.POINT + linkDistributorAttr;
            booleanQuery.filter(termsQuery(linkDistributor, distributorIdIn));
            booleanQuery.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
            booleanQuery.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(linkDistributor);
            List<PaasFormDataEntityExt> contractList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTRACT, booleanQuery, PaasFormDataEntityExt.class, fieldList);
            if (Objects.isNull(contractList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 获取经销商信用
            List<CreditLimitEntityExt> creditByCustomerIdList = saasCreditHelper.getCreditByCustomerIdIn(distributorIdIn, corpid);
            Set<Long> creditByDistributorIdSet = new HashSet<>();
            creditByCustomerIdList.forEach((item)->{
                creditByDistributorIdSet.add(item.getData() == null ? -1 : item.getData().getLong(CreditLimitEnum.CUSTOMER_ID.getAttr()));
            });
            // 获取经销商对应账号
            Map<String, Object> params = BeanUtil.convertBean2Map(distributorDeleteBatchDTO, true);
            params.put("ids", distributorIdIn);
            List<DistributorAccountEntity> distributorAccountList = distributorAccountModel.findEntitys(param);
            if (Objects.isNull(distributorAccountList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            //经销商对应的进入审批的联系人
            String distributorNameAttr = DistributorContactEnum.DISTRIBUTOR_NAME.getAttr();
            Set<Long> hasContactDistributorIdSet = new HashSet<>();
            List<PaasProcessDataEntity> approvalContactList = paasProcessDataModel.getInApprovalDataByIdCondition(XbbRefTypeEnum.CONTACT.getCode(), DistributorContactEnum.DISTRIBUTOR_NAME.getAttr(), distributorIdIn, corpid, Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(), FlowStatusEnum.IN_APPROVAL.getType()));
            approvalContactList.forEach((item) -> {
                JSONObject data = JSONObject.parseObject(item.getData());
                if (Objects.nonNull(data) && Objects.nonNull(data.get(distributorNameAttr)) && data.getLong(distributorNameAttr) > 0L) {
                    hasContactDistributorIdSet.add(data.getLong(distributorNameAttr));
                }
            });
            // 经销商对应进审批账号
            Set<Long> hasAccountDistributorIdSet = new HashSet<>();
            distributorAccountList.forEach((item)->{
                hasAccountDistributorIdSet.add(item.getDistributorId());
            });
            String distributorName4AccountAttr = DistributorAccountEnum.DISTRIBUTOR_NAME.getAttr();
            List<PaasProcessDataEntity> approvalAccountList = paasProcessDataModel.getInApprovalDataByIdCondition(XbbRefTypeEnum.DISTRIBUTOR_ACCOUNT.getCode(), distributorName4AccountAttr, distributorIdIn, corpid, Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(), FlowStatusEnum.IN_APPROVAL.getType()));
            approvalAccountList.forEach((item) -> {
                JSONObject data = JSONObject.parseObject(item.getData());
                if (Objects.nonNull(data) && Objects.nonNull(data.get(distributorName4AccountAttr)) && data.getLong(distributorName4AccountAttr) > 0L) {
                    hasAccountDistributorIdSet.add(data.getLong(distributorName4AccountAttr));
                }
            });
            // 经销商对应的进入审批的订货单
            Set<Long> hasContractCustomerId = new HashSet<>();
            contractList.forEach((item)->{
                JSONObject data = item.getData();
                if (Objects.nonNull(data) && Objects.nonNull(data.get(linkDistributorAttr)) && data.getLong(linkDistributorAttr) > 0L) {
                    hasContractCustomerId.add(data.getLong(linkDistributorAttr));
                }
            });
            List<PaasProcessDataEntity> approvalContractList = paasProcessDataModel.getInApprovalDataByIdCondition(XbbRefTypeEnum.CONTRACT.getCode(),OrderEnum.LINK_DISTRIBUTOR.getAttr(),distributorIdIn,corpid, Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
            approvalContractList.forEach((item)->{
                JSONObject data = JSONObject.parseObject(item.getData());
                if (Objects.nonNull(data) && Objects.nonNull(data.get(linkDistributorAttr)) && data.getLong(linkDistributorAttr) > 0L) {
                    hasContractCustomerId.add(data.getLong(linkDistributorAttr));
                }
            });

            UserVO loginUser = distributorDeleteBatchDTO.getLoginUser();
            Boolean noPermission = !loginUser.isAdminOrBoss() && !loginUser.isMaxDataPermission();
            List<String> userIdIn = new ArrayList<>();
            if (noPermission) {
                UserEntity userEntity = new UserEntity();
                BeanUtil.copyProperties(loginUser, userEntity);
                Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getCode(), null);
                if (Objects.equals(dataPermission, DataPermissionEnum.SELF.getCode())) {
                    //数据权限为本人时
                    userIdIn = Collections.singletonList(loginUser.getUserId());
                } else {
                    //数据权限不为本人时，需要判断下属员工是否是负责人
                    userIdIn = userModel.getSubIdListByDataPermission(dataPermission, loginUser.getUserId(), loginUser.getCorpid(), BasicConstant.ONE, false);
                }
            }
            // 预收款
            List<PaasProcessDataEntity> approvalPaymentSheetList = paasProcessDataModel.getInApprovalDataByIdAndTypeCondition(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), PaymentSheetEnum.CUSTOMER_ID.getAttr(),distributorIdIn,distributorDeleteBatchDTO.getCorpid(),Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
            Set<Long> hasApprovalPaymentSheetCustomerId = new HashSet<>();
            approvalPaymentSheetList.forEach((item)->{
                JSONObject data = JSONObject.parseObject(item.getData());
                if (Objects.nonNull(data) && Objects.nonNull(data.get(PaymentSheetEnum.CUSTOMER_ID.getAttr())) && data.getLong(PaymentSheetEnum.CUSTOMER_ID.getAttr()) > 0L) {
                    hasApprovalPaymentSheetCustomerId.add(data.getLong(PaymentSheetEnum.CUSTOMER_ID.getAttr()));
                }
            });
            List<PaasFormDataEntityExt> paymentSheetList = paymentSheetService.getPaymentSheetEsDataListByCustomerIds(distributorDeleteBatchDTO.getCorpid(),distributorIdIn,Arrays.asList(PaymentSheetTypeEnum.RED_PREPAYMENT.getCode(),PaymentSheetTypeEnum.PREPAYMENT.getCode()));
            Set<Long> hasPaymentSheetCustomerId = new HashSet<>();
            paymentSheetList.forEach((item)->{
                JSONObject data = item.getData();
                if (Objects.nonNull(data) && Objects.nonNull(data.get(PaymentSheetEnum.CUSTOMER_ID.getAttr())) && data.getLong(PaymentSheetEnum.CUSTOMER_ID.getAttr()) > 0L) {
                    hasPaymentSheetCustomerId.add(data.getLong(PaymentSheetEnum.CUSTOMER_ID.getAttr()));
                }
            });

            Iterator iterator = distributorList.iterator();
            while (iterator.hasNext()) {
                // 判断审批中
                CustomerEntityExt item = (CustomerEntityExt) iterator.next();
                Long distributorId = item.getId();
                if (hasContractCustomerId.contains(distributorId)) {
                    // 含有订货单的id
                    iterator.remove();
                    JSONObject data = item.getData();
                    if (Objects.nonNull(data) && Objects.nonNull(data.get(DistributorEnum.NAME.getAttr()))){
                        errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_ORDER_NOT_DEL));
                        errorDataList.add(data.getString(DistributorEnum.NAME.getAttr()));
                    }
                    continue;
                }
                if (hasContactDistributorIdSet.contains(distributorId)) {
                    // 有存在审批中联系人的id
                    iterator.remove();
                    JSONObject data = item.getData();
                    if (Objects.nonNull(data) && Objects.nonNull(data.get(DistributorEnum.NAME.getAttr()))) {
                        errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_DISTRIBUTOR_CONTACT_NOT_DEL));
                        errorDataList.add(data.getString(DistributorEnum.NAME.getAttr()));
                    }
                    continue;
                }
                if (hasAccountDistributorIdSet.contains(distributorId)) {
                    // 有存在审批中账号的id
                    iterator.remove();
                    JSONObject data = item.getData();
                    if (Objects.nonNull(data) && Objects.nonNull(data.get(DistributorEnum.NAME.getAttr()))) {
                        errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_DISTRIBUTOR_ACCOUNT_NOT_DEL));
                        errorDataList.add(data.getString(DistributorEnum.NAME.getAttr()));
                    }
                    continue;
                }
                if (creditByDistributorIdSet.contains(distributorId)) {
                    // 有存在信用额度
                    iterator.remove();
                    JSONObject data = item.getData();
                    if (Objects.nonNull(data) && Objects.nonNull(data.get(DistributorEnum.NAME.getAttr()))) {
                        errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_DISTRIBUTOR_CREDIT_NOT_DEL));
                        errorDataList.add(data.getString(DistributorEnum.NAME.getAttr()));
                    }
                    continue;
                }
                if(CollectionsUtil.isNotEmpty(hasApprovalPaymentSheetCustomerId)){
                    if(hasApprovalPaymentSheetCustomerId.contains(distributorId)){
                        // 存在审批中预收款
                        iterator.remove();
                        JSONObject data = item.getData();
                        if (Objects.nonNull(data) && Objects.nonNull(data.get(DistributorEnum.NAME.getAttr()))){
                            errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_DISTRIBUTOR_P_M_B_NOT_DEL));
                            errorDataList.add(data.getString(DistributorEnum.NAME.getAttr()));
                        }
                        continue;
                    }
                }
                if(CollectionsUtil.isNotEmpty(hasPaymentSheetCustomerId)){
                    if(hasPaymentSheetCustomerId.contains(distributorId)){
                        // 预收款（非审批），直接复制customerService中的
                        iterator.remove();
                        JSONObject data = item.getData();
                        if (Objects.nonNull(data) && Objects.nonNull(data.get(DistributorEnum.NAME.getAttr()))){
                            errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_DISTRIBUTOR_PAYMENTSHEET_NOT_DEL));
                            errorDataList.add(data.getString(DistributorEnum.NAME.getAttr()));
                        }
                        continue;
                    }
                }
                item.setDataId(distributorId);
                Integer isPublic = FastJsonHelper.getIntegerOrDefaultFromFormData(item.getData(), DistributorEnum.IS_PUBLIC.getAttr(), 0);
                // 除公海客户且不是最大的数据权限，自己或其下属不是负责人则不能删除该客户
                // 因经销商数据和客户数据存在一起，这里直接用客户businessType查询
                if (noPermission && !Objects.equals(isPublic, 1) && !saasDetailPermissionHelp.checkDelPermission(userIdIn, item, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                    iterator.remove();
                    JSONObject data = item.getData();
                    if (Objects.nonNull(data) && Objects.nonNull(data.get(DistributorEnum.NAME.getAttr()))) {
                        errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.NO_PERMISSION_DISTRIBUTOR_DEL));
                        errorDataList.add(data.getString(DistributorEnum.NAME.getAttr()));
                    }
                    continue;
                }
                allowDeleteDistributorId.add(distributorId);
            }
            List<String> errorTypeList = new ArrayList<>(errorTypeSet);
            distributorDeleteBatchVO.setErrorTypeList(errorTypeList);
            distributorDeleteBatchVO.setErrorDataList(errorDataList);
            // List<Long> isPublicCustomerIdIn = new ArrayList<>();
            if (!allowDeleteDistributorId.isEmpty()) {
                // List<UpdateDataEntity> updateDataList = new ArrayList<>();
                // allowDeleteDistributorId.forEach((item) -> {
                //     UpdateDataEntity updateDataEntity = new UpdateDataEntity();
                //     List<UpdateDataValueEntity> updateDataValueList = new ArrayList<>();
                // UpdateDataValueEntity isPublic = new UpdateDataValueEntity();
                // isPublic.setValue(1);
                // isPublic.setKey(CustomerManagementEnum.IS_PUBLIC.getAttr());
                // isPublic.setEsKey(CustomerManagementEnum.IS_PUBLIC.getAttr());
                // isPublicCustomerIdIn.add(item);
                // updateDataValueList.add(isPublic);
                //     updateDataEntity.setId(item);
                //     updateDataEntity.setCorpid(corpid);
                //     long now = DateUtil.getInt();
                //     updateDataEntity.setUpdateTime(now);
                //     updateDataEntity.setData(updateDataValueList);
                //     updateDataList.add(updateDataEntity);
                // });
                //查询名称
                BoolQueryBuilder builder = boolQuery();
                // 添加corpid,formId,del
                builder.filter(termQuery("corpid.keyword", corpid));
                builder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                builder.filter(termsQuery(StringConstant.DATA_ID, allowDeleteDistributorId));
                List<String> nameFieldList = new ArrayList<>();
                nameFieldList.add(DistributorEnum.getAttrConnectData(DistributorEnum.NAME));
                IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

                List<PaasFormDataEntityExt> nameList = esHelper.findByScroll(indexTypeEnum, builder, PaasFormDataEntityExt.class, nameFieldList);
                for (PaasFormDataEntityExt entityExt : nameList) {
                    JSONObject data = entityExt.getData();
                    String sheetName = FastJsonHelper.getStringOrDefaultFromFormData(data, DistributorEnum.NAME.getAttr(), "");
                    name.add(sheetName);
                }
                // if (!updateDataList.isEmpty()) {
                //     if (BasicConstant.ONE.equals(distributorDeleteBatchDTO.getSingleFlag())
                //             && BasicConstant.ONE.equals(updateDataList.size())) {
                //         customerModel.updateBatch(updateDataList, corpid, WriteRequest.RefreshPolicy.NONE);
                //     } else {
                //         customerModel.updateBatch(updateDataList, corpid);
                //     }
                // }
                // 彻底删除主数据
                if (CollectionsUtil.isNotEmpty(allowDeleteDistributorId)) {
                    customerModel.thoroughDeleteBatch(allowDeleteDistributorId, corpid, DelEnum.REMOVE_COMPLETELY.getDel());
                }
                // 取消关注
                // deleteCustomerFocus(distributorDeleteBatchDTO, allowDeleteDistributorId);
                // 删除发票
                invoiceIdIn = deleteInvoice(distributorDeleteBatchDTO, allowDeleteDistributorId);
                // 删除负责人
                CustomerUserDeleteBatchDTO customerUserDeleteBatchDTO = new CustomerUserDeleteBatchDTO();
                BeanUtil.copyProperties(distributorDeleteBatchDTO, customerUserDeleteBatchDTO);
                customerUserDeleteBatchDTO.setCustomerIdIn(allowDeleteDistributorId);
                customerUserService.deleteBatch(customerUserDeleteBatchDTO, WriteRequest.RefreshPolicy.NONE);
                // 删除机会
                // opportunityIdIn = deleteOpportunity(distributorDeleteBatchDTO, allowDeleteDistributorId);
                // 删除联系人
                contactIdIn = deleteContact(distributorDeleteBatchDTO, allowDeleteDistributorId);
                // 删除报价单
                // quotationIdIn = deleteQuotation(distributorDeleteBatchDTO, allowDeleteDistributorId);
                // 删除跟进记录
                FormDataThoroughDeleteDTO formDataThoroughDeleteDTO = new FormDataThoroughDeleteDTO();
                BeanUtil.copyProperties(distributorDeleteBatchDTO, formDataThoroughDeleteDTO);
                distributorCommunicateIdIn = deleteCustomerCommunicate(formDataThoroughDeleteDTO, allowDeleteDistributorId);
                //预收款余额表对应的删除
                BoolQueryBuilder payMBQuery = boolQuery();
                payMBQuery.filter(termsQuery(PaymentBalanceEnum.CUSTOMER_ID.getAttr(), distributorIdIn));
                payMBQuery.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
                payMBQuery.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                List<PaymentBalanceEntity> payMentBalanceList = esHelper.findByScroll(IndexTypeEnum.IDX_PAYMENT_BALANCE, payMBQuery, PaymentBalanceEntity.class, Arrays.asList("id",PaymentBalanceEnum.CUSTOMER_ID.getAttr(),PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr()));
                //预收款余额等于0,存id
                if(CollectionsUtil.isNotEmpty(payMentBalanceList)){
                    for (PaymentBalanceEntity paymentBalanceEntity : payMentBalanceList) {
                        deletePayMentBalanceId.add(paymentBalanceEntity.getId());
                    }
                }
                deletePayMentBalance(distributorDeleteBatchDTO,new ArrayList<>(deletePayMentBalanceId));
                // 删除跟进提醒
                PushNotifyDeleteDTO pushNotifyDeleteDTO = new PushNotifyDeleteDTO();
                BeanUtil.copyProperties(distributorDeleteBatchDTO, pushNotifyDeleteDTO);
                pushNotifyDeleteDTO.setNeedDelNotifyIdList(allowDeleteDistributorId);
                pushNotifyDeleteDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                pushNotifyService.deletePushNotify(pushNotifyDeleteDTO);
            }
            distributorDeleteBatchVO.setDeleteIds(allowDeleteDistributorId);
            distributorDeleteBatchVO.setErrorDataList(errorDataList);
            distributorDeleteBatchVO.setErrorTypeList(errorTypeList);
            distributorDeleteBatchVO.setErrorDataMemo(SaasDeleteHelp.getErrorDataMemo(errorTypeList, errorDataList));
            // TODO 移除公海标签
            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            // if (Objects.equals(1, distributorDeleteBatchDTO.getIsBusinessRule())) {
            //     operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            // }
            // 生成删除日志(区分单个删除和批量删除)
            String userId = distributorDeleteBatchDTO.getUserId();
            String userName = distributorDeleteBatchDTO.getLoginUserName();
            String nameStr = StringUtils.join(name, "，");
            if (allowDeleteDistributorId.size() > 1) {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getName(), allowDeleteDistributorId.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(DistributorEnum.NAME.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.DISTRIBUTOR, operateTypeEnum,
                        "", "", memo, distributorDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(allowDeleteDistributorId.size(), 1)) {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.DISTRIBUTOR, operateTypeEnum,
                        allowDeleteDistributorId.get(0).toString(), nameStr, memo, distributorDeleteBatchDTO.getHttpHeader());
            }
        } catch (Exception e) {
            updateRollback(distributorDeleteBatchDTO.getDataIdList(), corpid);
            distributorCommunicateService.updateRollback(distributorCommunicateIdIn, corpid);
            invoiceService.updateRollback(invoiceIdIn, corpid);
            // opportunityService.updateRollback(opportunityIdIn, corpid);
            distributorContactService.updateRollback(contactIdIn, corpid);
            // quotationService.updateRollback(quotationIdIn, corpid);
            paymentBalanceService.updateRollback(new ArrayList<>(deletePayMentBalanceId),corpid);
            LOG.error("distributorServiceImpl.deleteBatch 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return distributorDeleteBatchVO;
    }

    /**
     * 删除联系人
     *
     * @param distributorDeleteBatchDTO
     * @param allowDeleteDistributorId
     * @return java.util.List<java.lang.Long>
     * @throws XbbException
     * @author xinpeng.jiang
     * @date 2021/1/5 18:51
     * @version 1.0
     */
    private List<Long> deleteContact(DistributorDeleteBatchDTO distributorDeleteBatchDTO, List<Long> allowDeleteDistributorId) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        String corpid = distributorDeleteBatchDTO.getCorpid();
        List<Long> contactIdIn = new ArrayList<>();
        try {
            boolQueryBuilder.filter(termsQuery(StringConstant.JSON_DATA + StringConstant.POINT + DistributorContactEnum.DISTRIBUTOR_NAME.getAttr(), allowDeleteDistributorId));
            boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
            boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(StringConstant.DATA_ID);
            List<PaasFormDataEntityExt> contactList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTACT, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
            if (Objects.isNull(contactList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            contactList.forEach((item) -> {
                contactIdIn.add(item.getDataId());
            });
            if (!contactIdIn.isEmpty()) {
                DistributorContactDeleteBatchDTO distributorContactDeleteBatchDTO = new DistributorContactDeleteBatchDTO();
                BeanUtil.copyProperties(distributorDeleteBatchDTO, distributorContactDeleteBatchDTO, true);
                distributorContactDeleteBatchDTO.setDataIdList(contactIdIn);
                distributorContactService.deleteBatch(distributorContactDeleteBatchDTO);
                ContactUserDeleteBatchDTO contactUserDeleteBatchDTO = new ContactUserDeleteBatchDTO();
                BeanUtil.copyProperties(distributorDeleteBatchDTO, contactUserDeleteBatchDTO, true);
                contactUserDeleteBatchDTO.setContactIdIn(contactIdIn);
                contactUserService.deleteBatch(contactUserDeleteBatchDTO);
            }
        } catch (Exception e) {
            LOG.error("distributorServiceImpl.deleteContact 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return contactIdIn;
    }

    /**
     * 更新时回滚
     *
     * @param idIn
     * @param corpid
     * @throws XbbException
     */
    private void updateRollback(List<Long> idIn, String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", idIn);
        if (Objects.isNull(idIn) || idIn.isEmpty()) {
            return;
        }
        param.put(StringConstant.CORPID, corpid);
        List<CustomerEntityExt> customerList = customerModel.findEntitysWithoutSub(param);
        if (Objects.nonNull(customerList)) {
            IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

            for (CustomerEntityExt item : customerList) {
                PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
                BeanUtil.copyProperties(item, paasFormDataEntity);
                proEsHelper.reductionEsInUpdate(paasFormDataEntity, item.getId(), corpid, customerIndex);
            }
        }
    }

    @Override
    public DistributorEditAttrUpdateVO batchEditAttr(DistributorEditAttrUpdateDTO distributorEditAttrUpdateDTO) throws XbbException {
        DistributorEditAttrUpdateVO distributorEditAttrUpdateVO = new DistributorEditAttrUpdateVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(distributorEditAttrUpdateDTO, true);
            param.put("idIn", distributorEditAttrUpdateDTO.getDataIdList());
            List<CustomerEntityExt> distributorList = customerModel.findEntitys(param);
            if (Objects.isNull(distributorList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            List<Long> updateIdList = new ArrayList<>();
            List<DistributorUpdateDTO> distributorUpdateList = new ArrayList<>();
            distributorEditAttrUpdateDTO.getDataIdList().forEach((item) -> {
                DistributorUpdateDTO distributorUpdateDTO = new DistributorUpdateDTO();
                distributorUpdateDTO.setId(item);
                updateIdList.add(item);
                JSONObject data = ProSaveHelp.getBatchUpdateData(distributorEditAttrUpdateDTO.getFieldEditedList());
                distributorUpdateDTO.setData(data);
                distributorUpdateList.add(distributorUpdateDTO);
            });
            if (!distributorUpdateList.isEmpty()) {
                DistributorUpdateBatchDTO distributorUpdateBatchDTO = new DistributorUpdateBatchDTO();
                BeanUtil.copyProperties(distributorEditAttrUpdateDTO, distributorUpdateBatchDTO);
                distributorUpdateBatchDTO.setDistributorList(distributorUpdateList);
                distributorUpdateBatch(distributorUpdateBatchDTO);
                // if (CustomerManagementEnum.TYPE.getAttr().equals(distributorEditAttrUpdateDTO.getAttr())) {
                //     // TODO 推送
                // }
                distributorEditAttrUpdateVO.setUpdateIdList(updateIdList);
            }
            // 批量编辑日志
            List<String> updataItemList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> dataIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (CustomerEntityExt item : distributorList) {
                dataIdList.add(item.getId());
                JSONObject data = item.getData();
                String serialNo = item.getSerialNo();
                String opObjectName = data.getString(DistributorEnum.NAME.getAttr());
                StringBuilder sb = new StringBuilder();
                opObjectName = opObjectName == null ? serialNo : sb.append(serialNo).append("（").append(opObjectName).append("）").toString();
                updataItemList.add(opObjectName);
            }
            String updataItem = StringUtils.join(updataItemList, "，");
            String userId = distributorEditAttrUpdateDTO.getUserId();
            String corpid = distributorEditAttrUpdateDTO.getCorpid();
            String loginUserName = distributorEditAttrUpdateDTO.getLoginUserName();

            String changedLogItemsStr = logHandleHelp.getChangedLogItemsStr(distributorEditAttrUpdateDTO.getLogFieldEditedList());
            if (dataIdList.size() > 1) {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_BATCH_ATTR), loginUserName, XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getName(),
                        changedLogItemsStr, dataIdList.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getName());
                infoArrPojo.setContent(updataItem);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.DISTRIBUTOR, OperateTypeEnum.EDIT,
                        "", "", memo, distributorEditAttrUpdateDTO.getHttpHeader());
            } else if (Objects.equals(dataIdList.size(), 1)) {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_ATTR), loginUserName, XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getName(), updataItem,
                        changedLogItemsStr);
                mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.DISTRIBUTOR, OperateTypeEnum.EDIT,
                        dataIdList.get(0).toString(), updataItem, memo, distributorEditAttrUpdateDTO.getHttpHeader());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("distributorServiceImpl.batchEditAttr 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return distributorEditAttrUpdateVO;
    }

    private DistributorUpdateBatchVO distributorUpdateBatch(DistributorUpdateBatchDTO distributorUpdateBatchDTO) throws XbbException {
        DistributorUpdateBatchVO distributorUpdateBatchVO = new DistributorUpdateBatchVO();
        try {
            String corpid = distributorUpdateBatchDTO.getCorpid();
            List<UpdateDataEntity> updateList = new ArrayList<>();
            List<DistributorUpdateDTO> distributorUpdateList = distributorUpdateBatchDTO.getDistributorList();
            if (Objects.nonNull(distributorUpdateList) && !distributorUpdateList.isEmpty()) {
                distributorUpdateList.forEach((item)->{
                    updateList.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
            }
            if (!updateList.isEmpty()) {
                customerModel.updateBatch(updateList, corpid);
            }
        } catch (Exception e) {
            LOG.error("distributorServiceImpl.customerUpdateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return distributorUpdateBatchVO;
    }

    @Override
    public void formatData(SaasAnalysisDataDTO saasAnalysisDataDTO, JSONObject result) throws XbbException {

    }

    @Override
    public void formatUpdateExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        customerModel.formatUpdateExplainForDistributor(formatExplainDTO);
    }

    @Override
    public ListAppVO formatDistributorAppList(FormDataListDTO formDataListDTO, List<PaasFormDataEntityExt> esEntities, Integer totalCount) throws XbbException {
        List<AppListPojo> appListPojos = new ArrayList<>();
        Long formId = formDataListDTO.getFormId();


        for (PaasFormDataEntityExt distributor : esEntities) {
            JSONObject data = distributor.getData();
            Long distributorId = distributor.getDataId();
            Long appId = distributor.getAppId();
            Long menuId = distributor.getMenuId();
            String name = FastJsonHelper.getStringOrDefaultFromFormData(data, DistributorEnum.NAME.getAttr(), "");

            JSONObject others = new JSONObject();

            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<SummaryDataPoJo> lablesList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);
            //最后跟进时间
            String lastConnectTimeStr = FastJsonHelper.getStringOrDefaultFromFormData(data, DistributorEnum.LAST_CONNECT_TIME.getAttr(), I18nMessageUtil.getMessage(StringConstant.NEVER_CONNECT));
            // 客户最后跟进时间格式标识
            if(Objects.nonNull(data.get(FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getDbAlias())) && Objects.nonNull(lastConnectTimeStr)
                    && !"".equals(lastConnectTimeStr) && !I18nMessageUtil.getMessage(StringConstant.NEVER_CONNECT).equals(lastConnectTimeStr)){
                String lastConnectTime = data.get(FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getDbAlias()).toString();
                if(Objects.equals(lastConnectTime, "0")){
                    Long time = Long.valueOf(lastConnectTimeStr);
                    lastConnectTimeStr = DateUtil.getString(time * 1000L, DateUtil.SDFYMDHM);
                }
            }

            String finalLastConnectTimeStr = lastConnectTimeStr;
            summaryList.forEach(item -> {
                if (Objects.equals(item.getAttr(), DistributorEnum.LAST_CONNECT_TIME.getAttr())) {
                    item.setValue(Collections.singletonList(finalLastConnectTimeStr));
                } else if (Objects.equals(item.getAttr(), DistributorEnum.ADDRESS.getAttr())) {
                    item.setAttrName(DistributorEnum.ADDRESS.getAttrName());
                }
            });

            appListPojos.add(new AppListPojo(distributorId, titleList, summaryList, new JSONObject(), lablesList, others, appId, menuId, formId, name));
        }
        ListAppVO listAppVO = new ListAppVO();
        listAppVO.setList(appListPojos);
        listAppVO.setTotalCount(totalCount);
        return  listAppVO;
    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        formDataAddDTO.setSerialNo("");
        JSONObject dataJson = new JSONObject();
        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (FieldAttrEntityForImport fieldAttr : fieldAttrList) {
            String attr = fieldAttr.getAttr();
            Integer fieldType = fieldAttr.getFieldType();
            String attrName = fieldAttr.getAttrName();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);
            if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, fieldAttr, dataJson);
            } else {
                // 经销商导入没负责人，默认添加管理员
                if (Objects.equals(fieldAttr.getAttr(), DistributorEnum.OWNER_ID.getAttr())
                        && (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString()))) {
                    UserEntity adminUser = userModel.getAdminUser(importFormDataDTO.getCorpid());
                    if (Objects.isNull(adminUser)) {
                        throw new XbbException(DistributorErrorCodeEnum.API_ERROR_251011);
                    }
                    cellValue = adminUser.getName();
                }
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                if (ImportHelper.commonHandleFieldType.contains(fieldAttr.getFieldType())) {
                    importHelper.formatCommonField(dataJson, fieldAttr, cellValue);
                } else {
                    if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                        formDataAddDTO.setSerialNo(cellValue.toString());
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                        importHelper.formatLinkData(cellValue, fieldAttr, dataJson);
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                        importHelper.formatLinkDataMulti(cellValue, importFormDataDTO, fieldAttr, dataJson);
                    } else {
                        dataJson.put(attr, cellValue);
                    }
                }
            }
            if (Objects.equals(attr, CustomerManagementEnum.ADD_CONTACT.getAttr())) {
                if (Objects.nonNull(fieldAttr.getSubForm()) && Objects.nonNull(fieldAttr.getSubForm().getItems())) {
                    explainMap = ExplainUtil.getExplainMapByList(fieldAttr.getSubForm().getItems());
                }
            }
        }
        JSONArray contactArr = dataJson.getJSONArray(CustomerManagementEnum.ADD_CONTACT.getAttr());
        if (Objects.nonNull(contactArr) && !contactArr.isEmpty()) {
            for (int i = 0; i < contactArr.size(); i++) {
                JSONObject contactObj = contactArr.getJSONObject(i).getJSONObject(StringConstant.JSON_DATA);
                if (Objects.nonNull(contactObj.get(FieldTypeEnum.DEPARTMENTID.getAlias()))) {
                    Long departmentId = departmentService.verifyDepartment(importFormDataDTO, explainMap, contactObj);
                    contactArr.getJSONObject(i).put(FieldTypeEnum.DEPARTMENTID.getAlias(), departmentId);
                    contactObj.put(FieldTypeEnum.DEPARTMENTID.getAlias(), new ReturnUserAndDepartmentPojo(departmentId));
                }
            }
        }
        formDataAddDTO.setDataList(dataJson);
        return formDataAddDTO;
    }

    @Override
    public void formatExportValue(List<PaasFormDataEntityExt> paasFormDataESList, FormDataListDTO formDataListDTO, List<FieldAttrEntityForImport> fieldAttrList, Integer businessType) throws XbbException {
        FieldAttrEntityForImport contactField = null;
        for (FieldAttrEntityForImport fieldAttrEntityForImport : fieldAttrList) {
            if (Objects.equals(fieldAttrEntityForImport.getAttr(), DistributorEnum.ADD_CONTACT.getAttr())) {
                contactField = fieldAttrEntityForImport;
                continue;
            }
        }
        if (Objects.isNull(contactField)) {
            return;
        }
        List<Long> businessIdIn = new ArrayList<>();
        paasFormDataESList.forEach(paasFormDataEntityExt -> businessIdIn.add(paasFormDataEntityExt.getId()));
        String keyword = StringConstant.POINT + StringConstant.KEY_WORD;
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery(ParameterConstant.CORPID + keyword, formDataListDTO.getCorpid()));
        boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
        String esData = StringConstant.JSON_DATA + StringConstant.POINT;
        boolQueryBuilder.filter(termsQuery(esData + ContactEnum.CUSTOMER_NAME.getAttr() + keyword, businessIdIn));
        List<PaasFormDataEntityExt> customerLinkContactList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTACT, boolQueryBuilder, PaasFormDataEntityExt.class, null);
        Map<Long, List<PaasFormDataEntityExt>> contactMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        customerLinkContactList.forEach(contact -> {
            List<PaasFormDataEntityExt> contactEntityList = new ArrayList<>();
            Long linkCustomerId = contact.getData().getLong(ContactEnum.CUSTOMER_NAME.getAttr());
            if (contactMap.containsKey(linkCustomerId)) {
                contactEntityList.addAll(contactMap.get(linkCustomerId));
            }
            contactEntityList.add(contact);
            contactMap.put(linkCustomerId, contactEntityList);
        });
        PaasFormExplainEntity contactExplain = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.CONTACT.getCode(), formDataListDTO.getCorpid(), formDataListDTO.getDistributorMark());
        List<FieldAttrEntity> contactFieldList = JSONArray.parseArray(contactExplain.getExplains(), FieldAttrEntity.class);
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            JSONObject data = paasFormDataEntityExt.getData();
            List<PaasFormDataEntityExt> singleCustomerContactList = contactMap.getOrDefault(paasFormDataEntityExt.getId(), new ArrayList<>());
            JSONArray contactArray = new JSONArray();
            Map<String, Object> userMap = formDataListDTO.getUserMap();
            Map<String, Object> deptMap = formDataListDTO.getDeptMap();
            List<FieldAttrEntityForImport> fieldAttrEntityForImportList = JSON.parseArray(JSON.toJSONString(contactField.getSubForm().getItems()), FieldAttrEntityForImport.class);
            for (PaasFormDataEntityExt contactEntity : singleCustomerContactList) {
                JSONObject contactItemObj = contactEntity.getData();
                importHelper.formatCommonData4Export(userMap, deptMap, contactEntity, contactItemObj, contactFieldList, null, null, businessType, null);
                importHelper.formatDropDown4Export(fieldAttrEntityForImportList, contactItemObj, null);
                contactArray.add(contactItemObj);
            }
            data.put(CustomerManagementEnum.ADD_CONTACT.getAttr(), contactArray);
        }
    }


    /**
     * 删除发票
     * @author 吴峰
     * @date 2019/3/14 16:44
     * @param distributorDeleteBatchDTO 前端传参
     * @param allowDeleteCustomerId 需要删除的客户id
     * @return void
     * @throws XbbException 业务异常
     */
    private List<Long> deleteInvoice(DistributorDeleteBatchDTO distributorDeleteBatchDTO, List<Long> allowDeleteCustomerId) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        String corpid = distributorDeleteBatchDTO.getCorpid();
        List<Long> invoiceIdIn = new ArrayList<>();
        try {
            boolQueryBuilder.filter(termsQuery(StringConstant.JSON_DATA + StringConstant.POINT+ InvoiceEnum.CUSTOMER_NAME.getAttr(), allowDeleteCustomerId));
            boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
            boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(StringConstant.DATA_ID);
            List<PaasFormDataEntityExt> invoiceList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_INVOICE, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
            if (Objects.isNull(invoiceList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            invoiceList.forEach((item)->{
                invoiceIdIn.add(item.getDataId());
            });
            if (!invoiceIdIn.isEmpty()) {
                InvoiceDeleteBatchDTO invoiceDeleteBatchDTO = new InvoiceDeleteBatchDTO();
                BeanUtil.copyProperties(distributorDeleteBatchDTO, invoiceDeleteBatchDTO, true);
                invoiceDeleteBatchDTO.setDataIdList(invoiceIdIn);
                invoiceService.deleteBatch(invoiceDeleteBatchDTO, DelEnum.DELETE);
            }
        } catch (Exception e) {
            LOG.error("distributorServiceImpl.deleteInvoice 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return invoiceIdIn;
    }
    /**
     * 删除预收款余额为0的记录
     * @param distributorDeleteBatchDTO
     * @param deletePayMentBalanceId
     * @return
     * @throws XbbException
     */
    private List<Long> deletePayMentBalance(DistributorDeleteBatchDTO distributorDeleteBatchDTO, List<Long> deletePayMentBalanceId) throws XbbException {
        if(CollectionsUtil.isEmpty(deletePayMentBalanceId)){
            return deletePayMentBalanceId;
        }
        try {
            paymentBalanceService.deleteBatch(deletePayMentBalanceId,distributorDeleteBatchDTO.getCorpid());
        } catch (Exception e) {
            LOG.error("customerServiceImpl.deletePayMentBalance 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return deletePayMentBalanceId;
    }


    /**
     * 删除跟进记录
     * @author 吴峰
     * @date 2019/3/14 16:44
     * @param formDataThoroughDeleteDTO 前端传参
     * @param allowDeleteCustomerId 需要删除的客户id
     * @return void
     * @throws XbbException 业务异常
     */
    private List<Long> deleteCustomerCommunicate(FormDataThoroughDeleteDTO formDataThoroughDeleteDTO, List<Long> allowDeleteCustomerId) throws XbbException {

        String corpid = formDataThoroughDeleteDTO.getCorpid();
        List<Long> customerCommunicateIdIn = new ArrayList<>();
        try {
            if (CollectionsUtil.isEmpty(allowDeleteCustomerId)) {
                return new ArrayList<>();
            }
            CustomerCommunicateDeleteBatchDTO customerCommunicateDeleteBatchDTO = new CustomerCommunicateDeleteBatchDTO();
            BeanUtil.copyProperties(formDataThoroughDeleteDTO, customerCommunicateDeleteBatchDTO, true);
            Runnable runnable = () -> {
                try {
                    List<Long> deleteIdIn = new ArrayList<>();
                    allowDeleteCustomerId.forEach(item->{
                        if (Objects.nonNull(item)) {
                            deleteIdIn.add(item);
                        }
                    });
                    BoolQueryBuilder boolQueryBuilder = boolQuery();
                    boolQueryBuilder.filter(termsQuery(StringConstant.JSON_DATA + StringConstant.POINT+ CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(), deleteIdIn));
                    boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
                    boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                    List<String> fieldList = new ArrayList<>();
                    fieldList.add(StringConstant.DATA_ID);
                    List<PaasFormDataEntityExt> customerCommunicateList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
                    if (Objects.isNull(customerCommunicateList)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                    }
                    customerCommunicateList.forEach((item)->{
                        customerCommunicateIdIn.add(item.getDataId());
                    });
                    Integer allTotal = customerCommunicateList.size();
                    Integer pageSize = 100;
                    Integer index = allTotal/pageSize + 1;
                    Integer page = 0;
                    Integer toIndex = 100;
                    for (int j = 0; j < index; j++) {
                        if (toIndex > allTotal) {
                            toIndex = allTotal;
                        }
                        List<PaasFormDataEntityExt> resultList = customerCommunicateList.subList(page, toIndex);
                        if (CollectionsUtil.isNotEmpty(resultList)) {
                            List<Long> deleteList = new ArrayList<>();
                            resultList.forEach((item)->{
                                deleteList.add(item.getDataId());
                            });
                            customerCommunicateDeleteBatchDTO.setIdIn(deleteList);
                            customerCommunicateService.deleteBatch(customerCommunicateDeleteBatchDTO);
                            page = page + pageSize;
                            toIndex = page + pageSize;
                        }
                    }
                } catch (Exception e) {
                    LOG.error("customerServiceImpl.deleteCustomerCommunicate 执行出错：", e);
                }
            };
            threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);


        } catch (Exception e) {
            LOG.error("customerServiceImpl.deleteCustomerCommunicate 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customerCommunicateIdIn;
    }



}
